package cn.highset.modules.base.controller.api;

import cn.highset.base.ApiBaseController;
import cn.highset.common.annotation.IgnoreAuth;
import cn.highset.common.constant.CommonConstant;
import cn.highset.common.utils.CommonUtil;
import cn.highset.common.utils.ResultUtil;
import cn.highset.common.utils.SecurityUtil;
import cn.highset.common.utils.wechat.ApiUserUtils;
import cn.highset.common.utils.wechat.WxMaCryptUtils;
import cn.highset.modules.base.entity.User;
import cn.highset.modules.base.entity.UserMiniprogram;
import cn.highset.modules.base.service.UserMiniprogramService;
import cn.highset.modules.base.service.UserService;
import cn.highset.modules.base.vo.FullUserInfo;
import cn.highset.modules.base.vo.UserInfo;
import com.alibaba.fastjson.JSONObject;
import com.qiniu.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 类 名 称：ApiAuthController
 * 类 描 述：API登录授权
 * 创建时间：2019-06-15 10:32
 * 创 建 人：victor
 */
@Slf4j
@RestController
@Api(description = "API登录授权")
@RequestMapping("/api/auth")
@Transactional
public class ApiAuthController extends ApiBaseController {
    @Autowired
    private UserService userService;
    @Autowired
    private SecurityUtil securityUtil;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserMiniprogramService userMiniprogramService;

    /**
     * @name: 微信登录
     * @description: TODO
     * @return:
     * @date: 2019-06-15 10:41
     * @auther: victor
     */
    @ApiOperation(value = "微信登录")
    @IgnoreAuth
    @PostMapping("login_by_weixin")
    public Object loginByWeixin() {
        JSONObject jsonParam = this.getJsonRequest();
        FullUserInfo fullUserInfo = null;
        String code = "";
        if (!StringUtils.isNullOrEmpty(jsonParam.getString("code"))) {
            code = jsonParam.getString("code");
        }
        if (null != jsonParam.get("userInfo")) {
            fullUserInfo = jsonParam.getObject("userInfo", FullUserInfo.class);
        }
        if (null == fullUserInfo) {
            return new ResultUtil<>().setErrorMsg("登录失败");
        }

        Map<String, Object> resultObj = new HashMap<String, Object>();
        //
        UserInfo userInfo = fullUserInfo.getUserInfo();

        //获取openid
        String requestUrl = ApiUserUtils.getWebAccess(code);//通过自定义工具类组合出小程序需要的登录凭证 code
        log.info("》》》组合token为：" + requestUrl);
        JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);

        if (null == sessionData || StringUtils.isNullOrEmpty(sessionData.getString("openid"))) {
            return new ResultUtil<>().setErrorMsg("登录失败");
        }
        //验证用户信息完整性
        String sha1 = CommonUtil.getSha1(fullUserInfo.getRawData() + sessionData.getString("session_key"));
        if (!fullUserInfo.getSignature().equals(sha1)) {
            return new ResultUtil<>().setErrorMsg("登录失败");
        }
        User user = userService.findByWeixinOpenid(sessionData.getString("openid"));
        if (null == user) {
            user = new User();
            user.setUsername("微信用户" + UUID.randomUUID().toString());
            user.setNickName(userInfo.getNickName());
            user.setAvatar(userInfo.getAvatarUrl());
            String sex = "未知";
            if (userInfo.getGender() != null) {
                if (1 == userInfo.getGender()) {
                    sex = "男";
                } else if (2 == userInfo.getGender()) {
                    sex = "女";
                }
            }
            user.setSex(sex);
            String encryptPass = new BCryptPasswordEncoder().encode(sessionData.getString("openid"));
            user.setPassword(encryptPass);
            user.setType(CommonConstant.USER_TYPE_WX);
            user.setWeixinOpenid(sessionData.getString("openid"));
            user.setSessionKey(sessionData.getString("session_key"));
            userService.save(user);
        } else {
            user.setAvatar(userInfo.getAvatarUrl());
            user.setSessionKey(sessionData.getString("session_key"));
            user.setNickName(userInfo.getNickName());
            userService.update(user);
        }
        //小程序用户信息
        UserMiniprogram userMiniprogram = userMiniprogramService.findByUserid(user.getId());
        if (userMiniprogram == null) {
            userMiniprogram = new UserMiniprogram();
            userMiniprogram.setUserid(user.getId());
            userMiniprogramService.save(userMiniprogram);

        }
        //清除用户信息缓存
        redisTemplate.delete("user::" + user.getUsername());
        redisTemplate.delete("user:miniprogram::" + user.getId());
        String accessToken = securityUtil.getToken(user.getUsername(), true);

        if (null == userInfo || StringUtils.isNullOrEmpty(accessToken)) {
            return new ResultUtil<>().setErrorMsg("登录失败");
        }

        resultObj.put("token", accessToken);
        resultObj.put("userInfo", userInfo);
        resultObj.put("userId", user.getId());
        return new ResultUtil<Object>().setData(resultObj);
    }

    /**
     * @description: 解析手机号码
     * @return:
     * @date: 2019-06-17 09:41
     * @auther: victor
     */
    @ApiOperation(value = "解析手机号码", notes = "解析手机号码")
    @PostMapping("parse_phone_number")
    public Object parsePhoneNumber() {
        JSONObject jsonParam = this.getJsonRequest();
        String encryptedData = jsonParam.getString("encryptedData");
        String iv = jsonParam.getString("iv");
        if (StringUtils.isNullOrEmpty(encryptedData) || StringUtils.isNullOrEmpty(iv)) {
            return new ResultUtil<>().setErrorMsg("获取手机号码失败");
        }
        User user = securityUtil.getCurrUser();
        //AES解析后字符串
        String jsonstring = WxMaCryptUtils.decrypt(user.getSessionKey(), encryptedData, iv);
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(jsonstring);
        } catch (Exception e) {
            return new ResultUtil<>().setErrorMsg("获取手机号码失败");

        }
        //登录验证成功，返回thirdsession 与用户信息
        Map<String, Object> resultObj = new HashMap<>();
        resultObj.put("phoneNumber", jsonObject.getString("phoneNumber"));
        resultObj.put("purePhoneNumber", jsonObject.getString("purePhoneNumber"));
        resultObj.put("countryCode", jsonObject.getString("countryCode"));
        return new ResultUtil<Object>().setData(resultObj);
    }

}
